#include "stdafx.h"

List *create_list() {
	List *list;

	list = (List *)malloc(sizeof(List));
	list->head = (Node *)malloc(sizeof(Node));
	list->tail = (Node *)malloc(sizeof(Node));

	list->head->next = list->tail;
	list->head->prev = 0;
	
	list->tail->next = 0;
	list->tail->prev = list->head;

	return list;
}

void add_list(List *list, void *data) {
	Node *node;

	node = (Node *)malloc(sizeof(Node));
	node->object = data;
	node->next = list->tail;
	node->prev = list->tail->prev;
	list->tail->prev->next = node;
	list->tail->prev = node;
}

int remove_list(List *list, void *data) {
	Node *node;
	for(node = begin(list); node != end(list); node = node->next) {
		if(node->object == data) {
			remove_list_from_node(node);
			return 1;
		}
	}

	return 0;
}

void remove_list_from_node(Node *node) {
	node->prev->next = node->next;
	node->next->prev = node->prev;
	free(node);
}

void destroy_list(List *list) {
	Node *node = list->head;
	while(node != 0) {
		Node *tnode = node->next;
		free(node);
		node = tnode;
	}

	free(list);
}

Node *begin(List *list) {
	return list->head->next;
}

Node *rbegin(List *list) {
	return list->tail->prev;
}

Node *end(List *list) {
	return list->tail;
}

Node *rend(List *list) {
	return list->head;
}

int is_empty_list(List *list) {
	return begin(list) == end(list) && rbegin(list) == rend(list);
}

List *reset_list(List *list) {
	Node *node = begin(list);
	while(node != end(list)) {
		Node *tnode = node->next;
		free(node);
		node = tnode;
	}

	list->head->next = list->tail;
	list->head->prev = 0;

	list->tail->next = 0;
	list->tail->prev = list->head;

	return list;
}

void merge_list(List *list1, List *list2) {
	Node *node;

	for(node = begin(list2); node != end(list2); node = node->next) {
		add_list(list1, node->object);
	}
}

bool is_contains_list(List *list, void *data) {
	Node *node;

	for(node = begin(list); node != end(list); node = node->next) {
		if(node->object == data)
			return true;
	}

	return false;
}